{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f04dd603-a2d1-48ce-8c17-9f1dba8de1ee",
   "metadata": {},
   "source": [
    "Chapter 11\n",
    "\n",
    "# 特征值分解\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccafb456-2453-4c82-8a65-b1963a370cb2",
   "metadata": {},
   "source": [
    "这段代码从头到尾，围绕**矩阵的特征值分解（Eigendecomposition）**展开，辅以几何可视化手段，展示了矩阵 $A$ 如何将单位圆变换为一个椭圆，并指出该椭圆的主轴方向即为 $A$ 的特征向量，主轴的长度则由特征值决定。\n",
    "\n",
    "---\n",
    "\n",
    "首先，定义了一个对称实矩阵：\n",
    "\n",
    "$$\n",
    "A = \\begin{bmatrix} 1.25 & -0.75 \\\\ -0.75 & 1.25 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "这是一个 $2\\times 2$ 的对称矩阵，其特征值必为实数，特征向量可以正交化。\n",
    "\n",
    "接着使用 `np.linalg.eig(A)` 对矩阵 $A$ 进行特征值分解，得到两个部分：\n",
    "\n",
    "- $V$：由两个特征向量 $v_1, v_2$ 组成的矩阵，满足 $A v_i = \\lambda_i v_i$。\n",
    "- $\\Lambda$：一个对角矩阵，包含对应的特征值 $\\lambda_1, \\lambda_2$：\n",
    "\n",
    "$$\n",
    "\\Lambda = \\operatorname{diag}(\\lambda_1, \\lambda_2), \\quad\n",
    "A = V \\Lambda V^{-1}\n",
    "$$\n",
    "\n",
    "然后，分别提取了第一组和第二组特征值与特征向量，并验证了：\n",
    "\n",
    "$$\n",
    "A v_1 = \\lambda_1 v_1, \\quad A v_2 = \\lambda_2 v_2\n",
    "$$\n",
    "\n",
    "这验证了特征值分解的定义。\n",
    "\n",
    "---\n",
    "\n",
    "下面是几何可视化部分。\n",
    "\n",
    "首先，构造单位圆上 721 个点：\n",
    "\n",
    "$$\n",
    "(x_1, x_2) = (\\cos\\theta, \\sin\\theta), \\quad \\theta \\in [0, 2\\pi]\n",
    "$$\n",
    "\n",
    "这些点组成单位圆：\n",
    "\n",
    "$$\n",
    "\\text{unit\\_circle} = \\left[ \\begin{array}{c}\n",
    "\\cos\\theta_1 \\ \\sin\\theta_1 \\\\\n",
    "\\cos\\theta_2 \\ \\sin\\theta_2 \\\\\n",
    "\\vdots \\\\\n",
    "\\cos\\theta_n \\ \\sin\\theta_n \\\\\n",
    "\\end{array} \\right]\n",
    "$$\n",
    "\n",
    "接着对单位圆中的每个点应用线性变换 $A$，即对每个点 $x$ 计算 $Ax$，几何上是将单位圆通过 $A$ 线性变换为一个椭圆。变换形式为右乘 $A^\\top$：\n",
    "\n",
    "$$\n",
    "A_{\\text{unit circle}} = \\text{unit\\_circle} \\cdot A^\\top\n",
    "$$\n",
    "\n",
    "注意是 $A^\\top$，因为 NumPy 中是按行操作的。\n",
    "\n",
    "---\n",
    "\n",
    "然后绘制两个主要内容：\n",
    "\n",
    "1. 原始单位圆（虚线）\n",
    "2. 被 $A$ 变换后的椭圆（虚线）\n",
    "\n",
    "除此之外，还绘制了：\n",
    "\n",
    "- 特征向量 $v_1, v_2$（从原点出发的箭头）\n",
    "- 对应的变换结果 $A v_1, A v_2$\n",
    "\n",
    "由于特征向量在变换后只是被“拉伸”或“压缩”，方向保持不变，因此箭头 $v_i$ 和 $A v_i$ 是共线的。这种共线现象是特征向量的核心几何性质：\n",
    "\n",
    "$$\n",
    "A v_i = \\lambda_i v_i \\quad \\Rightarrow \\quad A \\text{作用在} v_i \\text{上仅改变其长度，不改变方向}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "最终图形展示：\n",
    "\n",
    "- 原始单位圆被 $A$ 拉伸成椭圆\n",
    "- 椭圆的主轴方向是 $A$ 的两个特征向量\n",
    "- 椭圆的半轴长度是对应特征值的大小\n",
    "\n",
    "这体现了特征值分解在几何中的作用：它告诉我们一个对称矩阵在空间中“变形”的本质结构，是将单位圆**沿着特征向量方向拉伸/压缩**，拉伸系数就是对应的特征值。\n",
    "\n",
    "---\n",
    "\n",
    "总的来说，这段代码用图像揭示了以下数学思想：\n",
    "\n",
    "- 线性变换 $A$ 如何作用于整个空间（特别是单位圆）\n",
    "- 特征值/特征向量的几何意义\n",
    "- 实对称矩阵总能正交对角化，所形成的椭圆主轴是特征向量方向\n",
    "\n",
    "它是连接**代数结构**（$A = V\\Lambda V^{-1}$）与**几何直观**（椭圆、方向、长度）的经典例子。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "932b77d1-1791-49ea-91bd-f4688e46eff5",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "954b7525-dcef-47cb-af13-40c741ca3891",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e80828cd-9788-4af3-ad4e-095deaca8ad0",
   "metadata": {},
   "source": [
    "## 构造矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "35d1b417-1522-4104-9847-5a8f99f686b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1.25,-0.75],\n",
    "              [-0.75,1.25]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48567261-f116-4d67-a519-cf6b8430325f",
   "metadata": {},
   "source": [
    "## 特征值分解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "281a3219-8b00-4067-a4ab-f945be8fe38e",
   "metadata": {},
   "outputs": [],
   "source": [
    "lambdas, V = np.linalg.eig(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "7c771707-bdaa-4667-953d-b13aef42b54e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2. , 0.5])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lambdas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "6ad0d55b-0e69-43f5-85ad-7be297c15065",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2. , 0. ],\n",
       "       [0. , 0.5]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Lambda = np.diag(lambdas)\n",
    "Lambda"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89ec6899-e8c8-4bba-b92b-ea6fcb70b713",
   "metadata": {},
   "source": [
    "## 第一组特征值、特征向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "25e3b054-e874-4a58-aaae-3152341717e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征值\n",
    "lambda_1 = lambdas[0]\n",
    "lambda_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "53b73ed9-248a-4f9b-ac09-89db4534dff7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.70710678],\n",
       "       [-0.70710678]])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征向量\n",
    "v_1 = V[:,[0]]\n",
    "v_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "5ec57861-2b31-4eb7-a0b0-f04afef32160",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.41421356],\n",
       "       [-1.41421356]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A @ v_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "f4db2b9f-802e-485c-84ae-c629074c5bd2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.41421356],\n",
       "       [-1.41421356]])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lambda_1 * v_1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c7a244a-a963-457e-9e4a-ba3c88801735",
   "metadata": {},
   "source": [
    "## 第二组特征值、特征向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "c9c828a7-1f0a-4d85-8aca-c8cac1c6cd1c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.49999999999999983"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征值\n",
    "lambda_2 = lambdas[1]\n",
    "lambda_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "e8f76b73-ad96-4af6-9051-618a1df52280",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.70710678],\n",
       "       [0.70710678]])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征向量\n",
    "v_2 = V[:,[1]]\n",
    "v_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "9279f681-03bc-4401-b02b-d898cdcc5c84",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.35355339],\n",
       "       [0.35355339]])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A @ v_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "b1acdf55-83a3-436f-babf-2950f444c085",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.35355339],\n",
       "       [0.35355339]])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lambda_2 * v_2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0f381e4-f8d1-4cc7-adee-2ccf5044379a",
   "metadata": {},
   "source": [
    "## 特征值分解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "c9aee0c8-00e1-452a-bb62-40e42dca9cff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.25, -0.75],\n",
       "       [-0.75,  1.25]])"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "V @ Lambda @ np.linalg.inv(V)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3282522c-3092-46a1-acf8-ee5092801dd1",
   "metadata": {},
   "source": [
    "## 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "fa4b90e1-3523-41bb-9347-29eb1f8fe0b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()  \n",
    "\n",
    "theta_array = np.linspace(0,2*np.pi,721)\n",
    "# 极坐标到直角坐标\n",
    "x1_array = np.cos(theta_array)\n",
    "x2_array = np.sin(theta_array)\n",
    "unit_circle = np.column_stack([x1_array,x2_array])\n",
    "\n",
    "A_unit_circle = unit_circle @ A.T # A线性变换\n",
    "A_v1 = A@v_1\n",
    "A_v2 = A@v_2\n",
    "\n",
    "# 第一特征向量\n",
    "plt.quiver(0, 0, A_v1[0], A_v1[1], \n",
    "           angles='xy', scale_units='xy', \n",
    "           scale=1, color='#FF00CF', zorder = 1e5)\n",
    "plt.quiver(0, 0, v_1[0], v_1[1], \n",
    "           angles='xy', scale_units='xy', \n",
    "           scale=1, color='#FF00CF', zorder = 1e5)\n",
    "\n",
    "# 第二特征向量\n",
    "plt.quiver(0, 0, A_v2[0], A_v2[1], \n",
    "           angles='xy', scale_units='xy', \n",
    "           scale=1, color='#FFBD00', zorder = 1e5)\n",
    "plt.quiver(0, 0, v_2[0], v_2[1], \n",
    "           angles='xy', scale_units='xy', \n",
    "           scale=1, color='#FFBD00', zorder = 1e5)\n",
    "\n",
    "# 绘制变换前后单位圆\n",
    "plt.plot(A_unit_circle[:,0],A_unit_circle[:,1], c = 'k', ls = '--')\n",
    "plt.plot(unit_circle[:,0],unit_circle[:,1], c = 'k', ls = '--')\n",
    "\n",
    "# 装饰\n",
    "plt.axvline(x=0, color='k', zorder=0)\n",
    "plt.axhline(y=0, color='k', zorder=0)\n",
    "ax.tick_params(axis='both', which='both', length=0, labelbottom=False, labelleft=False)\n",
    "ax.set_aspect(1)\n",
    "lim = 2; ax.set_xlim([-lim, lim]); ax.set_ylim([-lim, lim])\n",
    "plt.xticks(np.arange(-lim, lim)); plt.yticks(np.arange(-lim, lim))\n",
    "ax.grid(linestyle='--', linewidth=0.15, color=[0.8, 0.8, 0.8])  # 添加网格"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "070c3389-8048-43a3-baa7-6666009bce96",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
